package com.xbongbong.crm.perform.command.delete;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.crm.abstracts.AbstractCrmDeleteService;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.log.pojo.InfoArrPojo;
import com.xbongbong.paas.pojo.dto.FormDataDeleteBatchDTO;
import com.xbongbong.paas.pojo.vo.FormDataDeleteBatchVO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.parent.pojo.delete.ErrorDataPojo;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.marketManage.pojo.dto.MarketActivityUserDeleteBatchDTO;
import com.xbongbong.pro.marketManage.pojo.vo.MarketActivityUserDeleteBatchVO;
import com.xbongbong.pro.thread.ThreadPoolBeanConfig;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.MarketActivityUserEntity;
import com.xbongbong.saas.domain.entity.StaticForMarketActivityEntity;
import com.xbongbong.saas.domain.entity.ext.MarketActivityEntityExt;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.MarketActivityEnum;
import com.xbongbong.saas.model.MarketActivityForStaticModel;
import com.xbongbong.saas.model.MarketActivityModel;
import com.xbongbong.saas.model.MarketActivityUserModel;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @author sunshaoxiang
 * @ClassName MarketActivityDeleteServiceImpl
 * @Description 市场活动 删除 业务层
 * @Date 2022/6/17 15:25
 * @Version 1.0
 **/
@Service("marketActivityDeleteServiceImpl")
public class MarketActivityDeleteServiceImpl extends AbstractCrmDeleteService<PaasFormEntityExt, MarketActivityEntityExt> {

    public static final Logger LOGGER = LoggerFactory.getLogger(MarketActivityDeleteServiceImpl.class);

    @Resource
    private MarketActivityModel marketActivityModel;
    @Resource
    private EsHelper esHelper;
    @Resource
    private MarketActivityUserModel marketActivityUserModel;
    @Resource
    private ThreadPoolBeanConfig threadPoolBeanConfig;
    @Resource
    private MarketActivityForStaticModel marketActivityForStaticModel;
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
    @Resource
    private MongoLogHelp mongoLogHelp;

    @Override
    public List<Integer> businessType() {
        return Collections.singletonList(XbbRefTypeEnum.MARKET_ACTIVITY.getCode());
    }

    @Override
    public FormDataDeleteBatchVO deleteBatchNoPermission(FormDataDeleteBatchDTO formDataDeleteBatchDTO, PaasFormEntityExt form) throws XbbException {
        List<MarketActivityEntityExt> list = deleteEsData(formDataDeleteBatchDTO, formDataDeleteBatchDTO.getDataIdList(), formDataDeleteBatchDTO.getCorpid());
        List<Long> deleteIdIn = deleteData(formDataDeleteBatchDTO, formDataDeleteBatchDTO.getDataIdList(), list, formDataDeleteBatchDTO.getCorpid());
        ErrorDataPojo errorDataPojo = new ErrorDataPojo();
        errorDataPojo.setDeleteList(deleteIdIn);
        log(formDataDeleteBatchDTO, list, errorDataPojo);
        return new FormDataDeleteBatchVO(new ArrayList<>(), new ArrayList<>(), "", deleteIdIn);
    }

    @Override
    public FormDataDeleteBatchVO deleteWorkflow(FormDataDeleteBatchDTO formDataDeleteBatchDTO) throws XbbException {
        List<Long> contactIdIn = formDataDeleteBatchDTO.getDataIdList();
        String corpid = formDataDeleteBatchDTO.getCorpid();
        marketActivityModel.deleteBatch(contactIdIn, corpid);
        marketActivityUserModel.batchDeleteById( corpid, contactIdIn, WriteRequest.RefreshPolicy.NONE);

        return new FormDataDeleteBatchVO();
    }

    @Override
    public List<MarketActivityEntityExt> deleteEsData(FormDataDeleteBatchDTO formDataDeleteBatchDTO, List<Long> dataIdIn, String corpid) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("idIn", dataIdIn);
        param.put("del", DelEnum.NORMAL.getDel());
        List<MarketActivityEntityExt> list = marketActivityModel.findEntitys(param);
        if (Objects.isNull(list)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }

        BoolQueryBuilder marketActivityBuilder = new BoolQueryBuilder();
        // 添加corpid,formId,del
        marketActivityBuilder.filter(termQuery("corpid.keyword", corpid));
        marketActivityBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        marketActivityBuilder.filter(termsQuery(StringConstant.DATA_ID, dataIdIn));
        List<String> fieldList = new ArrayList<>();
        fieldList.add(FieldTypeEnum.SERIALNO.getAlias());
        fieldList.add(MarketActivityEnum.getAttrConnectData(MarketActivityEnum.NAME));
        list = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_MARKET_ACTIVITY, marketActivityBuilder, PaasFormDataEntityExt.class, fieldList);
        return list;
    }

    @Override
    public ErrorDataPojo notAllowData(FormDataDeleteBatchDTO formDataDeleteBatchDTO, List<MarketActivityEntityExt> list) throws XbbException {
        //市场活动没有不可删除数据
        return new ErrorDataPojo();
    }

    @Override
    public List<Long> deleteData(FormDataDeleteBatchDTO formDataDeleteBatchDTO, List<Long> idIn, List<MarketActivityEntityExt> list, String corpid) throws XbbException {
        // 删除市场活动
        if(!idIn.isEmpty()) {
            if(BasicConstant.ONE.equals(formDataDeleteBatchDTO.getSingleFlag())
                    && BasicConstant.ONE.equals(idIn.size())){
                marketActivityModel.deleteByKey(idIn.get(0),corpid);
            }else {
                marketActivityModel.deleteBatch(idIn, corpid);
            }
            formDataDeleteBatchDTO.setDataIdList(idIn);
            deleteStaticMarket(corpid, idIn);
        }
        // 删除市场活动团队关系
        MarketActivityUserDeleteBatchDTO marketActivityUserDeleteBatchDTO = new MarketActivityUserDeleteBatchDTO();
        BeanUtil.copyProperties(formDataDeleteBatchDTO, marketActivityUserDeleteBatchDTO);
        marketActivityUserDeleteBatchDTO.setDataIdIn(idIn);
        batchDelete(marketActivityUserDeleteBatchDTO);
        return idIn;
    }

    /**
     * 批量删除数据
     * 重构前 -> com.xbongbong.saas.service.impl.MarketActivityUserServiceImpl#deleteBatch(com.xbongbong.pro.marketManage.pojo.dto.MarketActivityUserDeleteBatchDTO)
     * @param marketActivityUserDeleteBatchDTO
     */
    private MarketActivityUserDeleteBatchVO batchDelete(MarketActivityUserDeleteBatchDTO marketActivityUserDeleteBatchDTO) throws XbbException{
        MarketActivityUserDeleteBatchVO marketActivityUserDeleteBatchVO = new MarketActivityUserDeleteBatchVO();
        try {
            Map<String, Object> param = BeanUtil.convertBean2Map(marketActivityUserDeleteBatchDTO, true);
            List<MarketActivityUserEntity> marketActivityUserList = marketActivityUserModel.findEntitys(param);
            if (Objects.isNull(marketActivityUserList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            if (marketActivityUserList.isEmpty()) {
                return marketActivityUserDeleteBatchVO;
            }
            String corpid = marketActivityUserDeleteBatchDTO.getCorpid();
            if (!marketActivityUserList.isEmpty()) {
                List<MarketActivityUserEntity> updateCustomerUserList = new ArrayList<>();
                for (MarketActivityUserEntity item : marketActivityUserList) {
                    MarketActivityUserEntity marketActivityUserEntity = new MarketActivityUserEntity();
                    marketActivityUserEntity.setId(item.getId());
                    marketActivityUserEntity.setDataId(item.getDataId());
                    marketActivityUserEntity.setCorpid(corpid);
                    marketActivityUserEntity.setDel(-1);
                    long now = DateUtil.getInt();
                    marketActivityUserEntity.setUpdateTime(now);
                    updateCustomerUserList.add(marketActivityUserEntity);
                }
                if (!updateCustomerUserList.isEmpty()) {
                    marketActivityUserModel.updateBatch(updateCustomerUserList, corpid);
                }
            }
        } catch (Exception e) {
            LOGGER.error("MarketActivityUserServiceImpl.deleteBatch 执行出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return marketActivityUserDeleteBatchVO;
    }

    /**
     * 处理编辑接口(市场活动统计中间表)cl
     * @param corpid
     * @param idIn
     */
    public void deleteStaticMarket(String corpid, List<Long> idIn) {
        Runnable runnable = () -> {
            try {
                deleteBatchMarketActivity(idIn, XbbRefTypeEnum.MARKET_ACTIVITY ,corpid, DelEnum.DELETE.getDel());
            } catch (Exception e) {
            }
        };
        threadPoolBeanConfig.staticsMarketData().execute(runnable);
    }

    /**
     * 重构前 -> com.xbongbong.saas.service.impl.MarketActivityForStaticServiceImpl#deleteBatchMarketActivity(java.util.List, com.xbongbong.saas.enums.XbbRefTypeEnum, java.lang.String, java.lang.Integer)
     * //todo 暂时放在这里
     * @param idIn
     * @param marketActivity
     * @param corpid
     * @param del
     */
    private void deleteBatchMarketActivity(List<Long> idIn, XbbRefTypeEnum marketActivity, String corpid, Integer del) throws XbbException{
        if (idIn.size()==0){
            return;
        }
        // 这个优先级最高,必须得最先处理
        List<Long> otherNeedDel = new ArrayList<>();
        List<Long> delIds = new ArrayList<>();
        List<Long> updateIds = new ArrayList<>();

        IndexTypeEnum indexTypeEnum = IndexTypeEnum.IDX_STATICS_MARKET_DATA;
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        // 这里暂不处理这个del条件
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, indexTypeEnum.getType()));
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        SearchRequest searchRequest = new SearchRequest(indexTypeEnum.getIndex());
        List<StaticForMarketActivityEntity> staticList = new ArrayList<>();
        StaticForMarketActivityEntity staticForMarketActivityEntity = new StaticForMarketActivityEntity();
        long count;
        boolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
        boolQueryBuilder.filter(termsQuery("marketId", idIn));
        sourceBuilder.query(boolQueryBuilder);
        searchRequest.source(sourceBuilder);
        count = xbbElasticsearchRestTemplate.count(searchRequest, PaasFormDataEntityExt.class);
        getDelIds(delIds, sourceBuilder, searchRequest, count);
        if (otherNeedDel.size()>0){
            marketActivityForStaticModel.deleteBatch(otherNeedDel,corpid, DelEnum.DELETE.getDel());
        }

        if (delIds.size()>0){
            // 可能需要改动, listEntitys可能数量有点多
            marketActivityForStaticModel.deleteBatch(delIds, corpid, del);
        }
        if (staticList.size()>0){
            marketActivityForStaticModel.insertBatch(staticList, corpid);
        }
    }

    /**
     * 重构前 -> com.xbongbong.saas.service.impl.MarketActivityForStaticServiceImpl#getDelIds(java.util.Collection, org.elasticsearch.search.builder.SearchSourceBuilder, org.elasticsearch.action.search.SearchRequest, long)
     * @param delIds
     * @param sourceBuilder
     * @param searchRequest
     * @param count
     */
    private void getDelIds(List<Long> delIds, SearchSourceBuilder sourceBuilder, SearchRequest searchRequest, long count) throws XbbException{
        for (int i = 0; i <= count / 100; i++) {
            PageRequest pageRequest = EsUtil.setPage(sourceBuilder, i + 1, 100);
            XbbAggregatedPage<StaticForMarketActivityEntity> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, StaticForMarketActivityEntity.class);
            List<StaticForMarketActivityEntity> content = esEntities.getContent();
            for (StaticForMarketActivityEntity item : content) {
                delIds.add(item.getDataId());
            }
        }
    }


    @Override
    public void log(FormDataDeleteBatchDTO formDataDeleteBatchDTO, List<MarketActivityEntityExt> marketActivityExtList, ErrorDataPojo errorDataPojo) throws XbbException {
        //查询名称
        List<String> nameList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for(PaasFormDataEntityExt marketActivity : marketActivityExtList){
            JSONObject data = marketActivity.getData();
            String name = FastJsonHelper.getStringOrDefaultFromFormData(data, MarketActivityEnum.NAME.getAttr(), "");
            nameList.add(name);
        }
        OperateTypeEnum operateTypeEnum = OperateTypeEnum.DELETE;
        if (Objects.equals(1, formDataDeleteBatchDTO.getIsBusinessRule())) {
            operateTypeEnum = OperateTypeEnum.RULE_DELETE;
        }
        //生成删除日志(区分单个删除和批量删除)
        String corpid = formDataDeleteBatchDTO.getCorpid();
        String userId = formDataDeleteBatchDTO.getUserId();
        String userName = formDataDeleteBatchDTO.getLoginUserName();
        List<Long> idIn = formDataDeleteBatchDTO.getDataIdList();

        String nameStr = StringUtils.join(nameList, "，");
        if(idIn.size() > 1){
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_DELETE_FORM_DETAIL), userName, XbbRefTypeEnum.MARKET_ACTIVITY.getName(), idIn.size());
            List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            InfoArrPojo infoArrPojo = new InfoArrPojo();
            infoArrPojo.setTitle(MarketActivityEnum.NAME.getAttrName());
            infoArrPojo.setContent(nameStr);
            infoArrPojoList.add(infoArrPojo);
            //操作日志
            mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.MARKET_ACTIVITY, operateTypeEnum,
                    "", "", memo, formDataDeleteBatchDTO.getHttpHeader());
        } else if (Objects.equals(idIn.size(), 1)){
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_DELETE_WORK), userName, XbbRefTypeEnum.MARKET_ACTIVITY.getName(), nameStr);
            mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.MARKET_ACTIVITY, operateTypeEnum,
                    idIn.get(0).toString(), nameStr, memo, formDataDeleteBatchDTO.getHttpHeader());
        }
    }

    @Override
    public void deleteAfter(List<Long> dataIdList, FormDataDeleteBatchDTO formDataDeleteBatchDTO, PaasFormEntityExt form) throws XbbException {
        lowCodeExecuteService(dataIdList, form.getSaasMark(), form.getBusinessType(), form.getId(), formDataDeleteBatchDTO.getCorpid());
        // 工作流，业务规则
        startWorkflow(formDataDeleteBatchDTO, form.getBusinessRules(), dataIdList);
    }

    @Override
    public void rollback(List<Long> list, String corpid) {

    }
}
